package ac.svn.accesscontrol.controller.user;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JOptionPane;

import ac.notification.event.INotificationListener;
import ac.notification.event.NotificationEvent;
import ac.notification.manager.NotificationRegistrar;
import ac.svn.accesscontrol.context.Context;
import ac.svn.accesscontrol.context.IContextConstants;
import ac.svn.accesscontrol.controller.ListingController;
import ac.svn.accesscontrol.manager.SVNInfoManager;
import ac.svn.accesscontrol.store.IConstants;
import ac.svn.accesscontrol.store.IResources;
import ac.svn.accesscontrol.store.ISVNIdentifier;
import ac.svn.accesscontrol.store.ISVNItem;
import ac.svn.accesscontrol.store.SVNGroup;
import ac.svn.accesscontrol.store.SVNUser;
import ac.svn.accesscontrol.ui.helper.ContentLister;
import ac.svn.accesscontrol.ui.helper.TextPaneLister;
import ac.svn.accesscontrol.ui.panel.UserBasicInfoEditorPanelI;
import ac.svn.accesscontrol.ui.panel.UserGroupEditorPanel;
import ac.svn.accesscontrol.utils.UIUtility;
import ac.svn.accesscontrol.utils.Utility;

public class UserGroupMembershipController implements IContextConstants,INotificationListener,ISVNIdentifier
,IResources
{
	private UserBasicInfoEditorPanelI infoEditorPanel;
	private SVNInfoManager infoManager;
	private TextPaneLister textPaneLister = null;
	private ContentLister contentLister;
	private Context  context;
	private JButton  addGroupButton,removeGroupButton,editGroupButton;

	public UserGroupMembershipController(UserBasicInfoEditorPanelI groupEditorPanel)
	{
		//Receive target components.
		this.infoEditorPanel = groupEditorPanel;

		initComponents();

		//Get common components from registry.
		contentLister = new ContentLister(UserGroupEditorPanel.ExportedComponents.C_UGM_AVL_GRP_LIST_VIEW,UserGroupEditorPanel.ExportedComponents.C_UGM_AVL_GRP_LIST_MODEL);
		contentLister.setListClrRequired(true);
		ListingController.getListingController().registerListerForNotifications(contentLister, ListingController.GROUP);

		//Get Reference to SVNInformation Manager
		infoManager = SVNInfoManager.getInfoManager();

		//Register listeners to UI
		registerListeners();

		//Register for system notifications.
		NotificationRegistrar.registerListener(this);
	}

	private void initComponents() {

		addGroupButton = infoEditorPanel.getBtnAddGroup();
		addGroupButton.setToolTipText("Add a new Group!");

		editGroupButton = infoEditorPanel.getEditAddGroup();
		editGroupButton.setToolTipText("Edit selected Group!");

		removeGroupButton = infoEditorPanel.getBtnDeleteGroup();
		removeGroupButton.setToolTipText("Delete selected Group!");
	}

	private void registerListeners() 
	{
		UIUtility.addPopupListener(infoEditorPanel.getListAvailableGroups(), IConstants.VALUE_POPUP_TYPE_GROUP);
		
		infoEditorPanel.getBtnAdd().addActionListener(new ActionListener() 
		{
			@Override
			public void actionPerformed(ActionEvent arg0) 
			{
				//Add selected group to user.
				addGroupToUser();
			}
		});

		addGroupButton.addActionListener(new ActionListener() 
		{
			@Override
			public void actionPerformed(ActionEvent arg0) 
			{
				Utility.sendNotification(CMD_ADD_GROUP);
			}
		});

		editGroupButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				ISVNItem selectedGroup = (ISVNItem) infoEditorPanel.getListAvailableGroups().getSelectedValue();
				if(null != selectedGroup)
				{
					Utility.sendNotification(CMD_EDIT_GROUP, selectedGroup);
				}
				else
				{
					String message = "Make a selection on Available Group's List!";
					JOptionPane.showMessageDialog(null, message, "Make Selection", JOptionPane.INFORMATION_MESSAGE);
				}
			}
		});



		removeGroupButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				ISVNItem selectedGroup = (ISVNItem) infoEditorPanel.getListAvailableGroups().getSelectedValue();
				if(null != selectedGroup)
				{
					Utility.sendNotification(CMD_DELETE_GROUP, selectedGroup);
				}
				else
				{
					String message = "Make a selection on Available Group's List!";
					JOptionPane.showMessageDialog(null, message, "Make Selection", JOptionPane.INFORMATION_MESSAGE);
				}
			}
		});
	}

	public void addGroupToUser()
	{

		//Check context is given to Controller
		if(null != context)
		{
			//Get user from context.
			SVNUser svnUser = (SVNUser) context.get(KEY_OPERATION_PARAM);

			//Check user is there
			if(null != svnUser)
			{
				//Get selected group from available groups.
				SVNGroup svnGroup = (SVNGroup) infoEditorPanel.getListAvailableGroups().getSelectedValue();

				//Check if such selection is made on Available Groups List.
				if (null != svnGroup) 
				{
					//Get details of 					
					if (false == (svnUser.getGroups().contains(svnGroup.getGroupAlias()))) 
					{
						// Make modifications in User and Group mappings.
						svnUser.getGroups().add(svnGroup.getId());
						svnGroup.addMember(svnUser.getId());

						// Update new user and group object in central
						// repository
						infoManager.updateGroup(svnGroup);
						infoManager.updateUser(svnUser);

						// Update UI to reflect new state of group
						// membership.
						textPaneLister.listContents();

						// Update UI to reflect new set of accessible
						// locations.

						//Send notification to UserContactInformationManager.
						Utility.sendNotification(CMD_SHOW_USER_CONTACT_INFO);						

						//Update Groups List
						loadUserGroupDetails();

						//Notify UserLocationAccessController to Load new set of accessible location
						Utility.sendNotification(CMD_SHOW_USER_ACCESS_RIGHT);

					}
				}
				else
				{
					System.err.println("Group information not registered in information manager!");
				}
			}
			else
			{
				System.err.println("While updating group membership for user information not found!" );									
			}
		}
	}

	private void loadUserGroupDetails() 
	{
		//Check context is given to Controller
		if(null != context)
		{

			//Show all available groups
			contentLister.listItems(SVNInfoManager.getInfoManager().getAllGroups());

			//Get user from context.
			SVNUser svnUser = (SVNUser) context.get(KEY_OPERATION_PARAM);

			//Check user is there
			if(null != svnUser)
			{
				textPaneLister = new TextPaneLister(UserGroupEditorPanel.ExportedComponents.C_UGM_ASND_PANEL,svnUser.getId());
				textPaneLister.setImageUrl(IResources.LOC_ICN_GROUP_SMALL);
				textPaneLister.listContents();

				infoEditorPanel.getLblGroupCount().setText(	"Group(s): "+ String.valueOf(svnUser.getGroups().size()));
			}
		}
	}

	@Override
	public void receiveEvent(NotificationEvent notificationEvent) 
	{
		loadUserGroupDetails();
	}

	@Override
	public Set<String> declaredSubscriptionSet() 
	{
		Set<String> subscriptionSet = new HashSet<String>();
		subscriptionSet.add(CMD_SHOW_USER_GROUP_MEMSHIP);
		subscriptionSet.add(N_UIM_GROUP_MEM_UPDATE);
		subscriptionSet.add(N_GROUP_ADDED);
		subscriptionSet.add(N_GROUP_MODIFIED);
		subscriptionSet.add(N_GROUP_REMOVED);
		return subscriptionSet;
	}

	/**
	 * @return the context
	 */
	public Context getContext() {
		return context;
	}

	/**
	 * @param context the context to set
	 */
	public void setContext(Context context) {
		this.context = context;
	}



}
